<template>
  <div class="dynamic-form">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-width="config.labelWidth || '80px'"
      :label-position="config.labelPosition || 'right'"
      :size="config.size || 'default'"
      :disabled="config.disabled"
      class="dynamic-form-container"
    >
      <!-- 动态渲染表单字段 -->
      <template v-for="field in config.fields" :key="field.prop">
        <el-form-item 
          :label="field.label" 
          :prop="field.prop"
          :required="field.required"
        >
          <!-- 输入框 -->
          <el-input
            v-if="field.type === 'input' || field.type === 'text'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :type="field.inputType || 'text'"
            :clearable="field.clearable !== false"
            :prefix-icon="field.prefixIcon"
            :suffix-icon="field.suffixIcon"
            :maxlength="field.maxlength"
            :show-word-limit="field.showWordLimit"
          />
          
          <!-- 下拉选择框 -->
          <el-select
            v-else-if="field.type === 'select'"
            v-model="formData[field.prop]"
            :placeholder="field.placeholder || `请选择${field.label}`"
            :clearable="field.clearable !== false"
            :multiple="field.multiple"
            :filterable="field.filterable"
          >
            <el-option
              v-for="option in field.options || []"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
          
          <!-- 日期选择器 -->
          <el-date-picker
            v-else-if="field.type === 'date'"
            v-model="formData[field.prop]"
            :type="field.dateType || 'date'"
            :placeholder="field.placeholder || `请选择${field.label}`"
            :format="field.format"
            :value-format="field.valueFormat"
            :clearable="field.clearable !== false"
          />
          
          <!-- 开关 -->
          <el-switch
            v-else-if="field.type === 'switch'"
            v-model="formData[field.prop]"
            :active-text="field.activeText"
            :inactive-text="field.inactiveText"
          />
          
          <!-- 单选框 -->
          <el-radio-group
            v-else-if="field.type === 'radio'"
            v-model="formData[field.prop]"
          >
            <el-radio
              v-for="option in field.options || []"
              :key="option.value"
              :label="option.value"
            >
              {{ option.label }}
            </el-radio>
          </el-radio-group>
          
          <!-- 复选框 -->
          <el-checkbox-group
            v-else-if="field.type === 'checkbox'"
            v-model="formData[field.prop]"
          >
            <el-checkbox
              v-for="option in field.options || []"
              :key="option.value"
              :label="option.value"
            >
              {{ option.label }}
            </el-checkbox>
          </el-checkbox-group>
          
          <!-- 文本域 -->
          <el-input
            v-else-if="field.type === 'textarea'"
            v-model="formData[field.prop]"
            type="textarea"
            :placeholder="field.placeholder || `请输入${field.label}`"
            :rows="field.rows || 3"
            :maxlength="field.maxlength"
            :show-word-limit="field.showWordLimit"
          />
          
          <!-- 自定义插槽 -->
          <slot
            v-else-if="field.type === 'slot'"
            :name="field.slotName || field.prop"
            :field="field"
            :value="formData[field.prop]"
            :update="(value) => formData[field.prop] = value"
          />
        </el-form-item>
      </template>
      
      <!-- 表单操作按钮 -->
      <el-form-item v-if="config.showButtons !== false">
        <el-button 
          type="primary" 
          :loading="loading" 
          @click="handleSubmit"
        >
          {{ config.submitText || '提交' }}
        </el-button>
        <el-button 
          v-if="config.showReset !== false" 
          @click="handleReset"
        >
          {{ config.resetText || '重置' }}
        </el-button>
        <slot name="extra-buttons" />
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, watch, computed } from 'vue'
  import type { FormInstance, FormRules } from 'element-plus'

  // 定义表单字段配置接口
  interface FormField {
    prop: string
    label: string
    type: 'input' | 'text' | 'select' | 'date' | 'switch' | 'radio' | 'checkbox' | 'textarea' | 'slot'
    required?: boolean
    placeholder?: string
    options?: Array<{ label: string; value: any }>
    inputType?: 'text' | 'password' | 'number' | 'email'
    clearable?: boolean
    prefixIcon?: string
    suffixIcon?: string
    maxlength?: number
    showWordLimit?: boolean
    multiple?: boolean
    filterable?: boolean
    dateType?: 'date' | 'datetime' | 'daterange'
    format?: string
    valueFormat?: string
    activeText?: string
    inactiveText?: string
    rows?: number
    slotName?: string
  }

  // 定义表单配置接口
  interface FormConfig {
    fields: FormField[]
    labelWidth?: string
    labelPosition?: 'left' | 'right' | 'top'
    size?: 'large' | 'default' | 'small'
    disabled?: boolean
    showButtons?: boolean
    showReset?: boolean
    submitText?: string
    resetText?: string
  }

  // 组件Props
  interface Props {
    config: FormConfig
    modelValue?: Record<string, any>
    loading?: boolean
  }

  const props = withDefaults(defineProps<Props>(), {
    modelValue: () => ({}),
    loading: false
  })

  const emit = defineEmits<{
    'update:modelValue': [value: Record<string, any>]
    submit: [formData: Record<string, any>]
    reset: []
  }>()

  const formRef = ref<FormInstance>()
  
  // 表单数据
  const formData = reactive<Record<string, any>>({})
  
  // 初始化表单数据
  const initFormData = () => {
    // 清空现有数据
    Object.keys(formData).forEach(key => {
      delete formData[key]
    })
    
    // 设置默认值
    props.config.fields.forEach(field => {
      const defaultValue = props.modelValue[field.prop] ?? 
                          (field.type === 'checkbox' ? [] : 
                           field.type === 'switch' ? false : '')
      formData[field.prop] = defaultValue
    })
  }
  
  // 监听配置变化重新初始化
  watch(() => props.config, initFormData, { immediate: true })
  
  // 监听外部传入的modelValue变化
  watch(() => props.modelValue, (newVal) => {
    Object.keys(newVal).forEach(key => {
      if (formData[key] !== newVal[key]) {
        formData[key] = newVal[key]
      }
    })
  }, { deep: true })
  
  // 监听表单数据变化，触发update事件
  watch(formData, (newVal) => {
    emit('update:modelValue', { ...newVal })
  }, { deep: true })
  
  // 表单验证规则
  const formRules = computed<FormRules>(() => {
    const rules: FormRules = {}
    props.config.fields.forEach(field => {
      if (field.required) {
        rules[field.prop] = [
          { required: true, message: `${field.label}不能为空`, trigger: field.type === 'select' ? 'change' : 'blur' }
        ]
      }
    })
    return rules
  })
  
  // 提交表单
  const handleSubmit = async () => {
    try {
      const valid = await formRef.value?.validate()
      if (valid) {
        emit('submit', { ...formData })
      }
    } catch (error) {
      console.error('表单验证失败:', error)
    }
  }
  
  // 重置表单
  const handleReset = () => {
    formRef.value?.resetFields()
    emit('reset')
  }
  
  // 暴露方法给父组件
  defineExpose({
    validate: () => formRef.value?.validate(),
    resetFields: () => formRef.value?.resetFields(),
    clearValidate: () => formRef.value?.clearValidate(),
    getFormData: () => ({ ...formData })
  })
</script>

<style scoped lang="less">
  .dynamic-form {
    width: 100%;
    
    .dynamic-form-container {
      .el-form-item {
        margin-bottom: 20px;
        
        &:last-child {
          margin-bottom: 0;
        }
      }
    }
  }
</style>